// (c) 2008 Kickstone Technology Ltd

#include "stdafx.h"
#include "WebBrowserEventSink.h"
#include "ButtonDemoBHO.h"
#include <exdispid.h>

#define DISPID_WINDOWSTATECHANGED 283


CWebBrowserEventSink::CWebBrowserEventSink(IWebBrowserEventCallback *bho) : m_BHO(bho), m_dwCookie(0) {
}

CWebBrowserEventSink::~CWebBrowserEventSink() {
}

// Connect/Disconnect to the DWebBrowserEvents2 Source
bool CWebBrowserEventSink::advise(IWebBrowser2 *pBrowser) {
	HRESULT hr;

	if (!pBrowser)
		return false;

	m_spWebBrowser2=pBrowser;
	CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> spCPContainer=m_spWebBrowser2;

	if (spCPContainer != NULL) {
		CComPtr<IConnectionPoint> spConnectionPoint;

		hr = spCPContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &spConnectionPoint);
		if (SUCCEEDED(hr) && !m_dwCookie) {
			hr = spConnectionPoint->Advise((IDispatch*)this, &m_dwCookie);
			if (FAILED(hr))
				ATLTRACE("CWebBrowserEventSink: advise(): Failed\n\n");
		}
	}
	return SUCCEEDED(hr);
}

bool CWebBrowserEventSink::unadvise() {
	HRESULT hr;
	if (!m_spWebBrowser2)
		return false;

	CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> spCPContainer=m_spWebBrowser2;
	if (spCPContainer != NULL) {
		CComPtr<IConnectionPoint> spConnectionPoint;

		hr = spCPContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &spConnectionPoint);
		if (SUCCEEDED(hr) && m_dwCookie) {
			// Remove us from the list of people interested...
			hr = spConnectionPoint->Unadvise(m_dwCookie);
			if (FAILED(hr))
				ATLTRACE("CWebBrowserEventSink: unadise(): Failed\n\n");
			m_dwCookie=0;
			m_spWebBrowser2=NULL;
		}
	}
	return SUCCEEDED(hr);
}

// catch the DWebBrowserEvents2 events we require and call the appropriate function
HRESULT CWebBrowserEventSink::handleEvent(DISPID dispIdMember, DISPPARAMS *pDispParams){
	if (!pDispParams)
		return E_INVALIDARG;

	if (!m_BHO)
		return E_UNEXPECTED;

	HRESULT hr=S_OK;
	switch (dispIdMember) {
		case DISPID_BEFORENAVIGATE2:
			hr=m_BHO->onBeforeNavigate2(pDispParams->rgvarg[6].pdispVal, pDispParams->rgvarg[5].pvarVal, pDispParams->rgvarg[4].pvarVal, pDispParams->rgvarg[3].pvarVal, pDispParams->rgvarg[2].pvarVal, pDispParams->rgvarg[1].pvarVal, pDispParams->rgvarg[0].pboolVal); break;
		case DISPID_NAVIGATECOMPLETE2:
			hr=m_BHO->onNavigateComplete2(pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal); break;
		case DISPID_DOWNLOADBEGIN:
			hr=m_BHO->onDownloadBegin(); break;
		case DISPID_DOCUMENTCOMPLETE:
			hr=m_BHO->onDocumentComplete(pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal); break;
		case DISPID_QUIT:
		case DISPID_ONQUIT:
			hr=m_BHO->onQuit(); break;
		case DISPID_WINDOWSTATECHANGED:
			hr=m_BHO->onWindowStateChanged(pDispParams->rgvarg[0].lVal, pDispParams->rgvarg[1].lVal); break;
	}
	return hr;
}

// when we are deleted, release the pointer on the BHO
void CWebBrowserEventSink::finalRelease(){
	m_BHO->releaseBrowserSink();
}